package bishi;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author: 唐小尊
 * @email: 1171702529@qq.com
 * @cate: 2021/05/10 11:51
 */
class Festival {
    String name;//节日名
    LocalDate date;//开始时间
    int num;//放假日期

    public Festival(String name, LocalDate date, int num) {
        this.name = name;
        this.date = date;
        this.num = num;
    }
}
public class Node {
    private int[] days = new int[265];//除去了周末的时间
    private int size = 0;

    public Node() {
        Arrays.fill(this.days, -1);
    }

    /**
     * 某一天，在该月已经度过的周末数，用于求唯一hash
     *
     * @param date
     * @return
     */
    private int getFrontWeekendNum(LocalDate date) {
        int num = date.getDayOfMonth() - date.getDayOfWeek().getValue() + 2;
        return num / 7 * 2;
    }


    private int hash(LocalDate date) {
        return (date.getMonthValue() - 1) * 22 + date.getDayOfMonth() - getFrontWeekendNum(date) - 1;
    }

    private LocalDate dayToLocalDate(int day) {
        return LocalDate.of(day / 10000, day / 100 % 100, day % 100);
    }

    private int localDateToDay(LocalDate date) {
        return date.getYear() * 10000 + date.getMonthValue() * 100 + date.getDayOfMonth();
    }

    public void set(LocalDate date) {
        //不允许存周末！
        if (date.getDayOfWeek().getValue() > 5) {
            return;
        }
        days[hash(date)] = localDateToDay(date);
        size++;
    }

    public void remove(LocalDate date) {
        days[hash(date)] = -1;
        size--;
    }

    /**
     * 删除一部分存储的工作日
     *
     * @param date 开始时间
     * @param num  放假时长，一共删除num个，包括date
     */
    public void removeMany(LocalDate date, int num) {
        while (num > 0) {
            days[hash(date)] = -1;
            size--;
            date = date.plusDays(1);
            num--;
        }
    }

    public int getSize() {
        return size;
    }

    /**
     * 得到下一个工作日
     *
     * @param date
     * @return
     */
    public LocalDate getNext(LocalDate date) {
        for (int i = hash(date) + 1; i < days.length; i++) {
            if (days[i] != -1) {
                return dayToLocalDate(days[i]);
            }
        }
        return null;
    }

    /**
     * 得到一段时间所有的工作日
     *
     * @param from
     * @param to
     * @return
     */
    public List<LocalDate> queryBetween(LocalDate from, LocalDate to) {
        int start = hash(from);
        int end = hash(to);
        List<LocalDate> localDates = new ArrayList<>(end - start + 1);
        while (start <= end) {
            localDates.add(dayToLocalDate(days[start]));
            start++;
        }
        return localDates;
    }

    /**
     * 判断是否存在数组中，即判断是否为工作日
     *
     * @param date
     * @return
     */
    public boolean isExist(LocalDate date) {
        return days[hash(date)] != -1;
    }
}
